package com.example.ricebibackend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.ricebibackend.common.errorcode.ServiceErrorCodeConstants;
import com.example.ricebibackend.common.exception.ServiceException;
import com.example.ricebibackend.common.utils.EncryptUtil;
import com.example.ricebibackend.common.utils.JWTUtil;
import com.example.ricebibackend.common.utils.RegexUtil;
import com.example.ricebibackend.controller.param.UserLoginBaseParam;
import com.example.ricebibackend.controller.param.UserLoginPasswordParam;
import com.example.ricebibackend.controller.param.UserLoginVerifyCodeParam;
import com.example.ricebibackend.controller.param.UserRegisterParam;
import com.example.ricebibackend.dao.dataobject.PhoneNumberEncrypt;
import com.example.ricebibackend.dao.dataobject.UserDO;
import com.example.ricebibackend.dao.mapper.UserMapper;
import com.example.ricebibackend.service.UserService;
import com.example.ricebibackend.service.VerificationCodeService;
import com.example.ricebibackend.service.dto.UserLoginDTO;
import com.example.ricebibackend.service.dto.UserRegisterDTO;
import com.example.ricebibackend.service.enums.IdentityEnum;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;
    @Resource
    private VerificationCodeService verificationCodeService;

    @Override
    public UserLoginDTO login(UserLoginBaseParam param) {
        if (param instanceof UserLoginVerifyCodeParam codeParam) {
            // 验证码登录
            return loginByCode(codeParam);
        } else if (param instanceof UserLoginPasswordParam pwdParam) {
            // 密码登录
            return loginByPassword(pwdParam);
        } else {
            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_NOT_EXISTS);
        }
    }

    /**
     * 根据密码进行登录
     * @param pwdParam 密码登录参数
     * @return DTO对象
     */
    private UserLoginDTO loginByPassword(UserLoginPasswordParam pwdParam) {
        // 1. 校验参数
        if (pwdParam == null) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_PARAM_NULL);
        }
        // 2. 根据用户名查询用户
        UserDO dbUser = userMapper.selectOne(new QueryWrapper<UserDO>()
                .eq("user_name", pwdParam.getUserName()));
        // 3. 验证用户身份信息
        if (dbUser == null) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_NOT_EXISTS);
        }
        // 4. 校验用户密码
        if (!RegexUtil.checkPassword(pwdParam.getPassword())) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_PWD_ERROR);
        }
        if (!dbUser.getPassword().equals(
                EncryptUtil.encryptBySha256(pwdParam.getPassword()))
        ) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_PWD_ERROR);
        }
        // 5. 封装DTO返回对象
        Map<String, Object> claim = new HashMap<>();
        claim.put("id", dbUser.getId());
        UserLoginDTO userLoginDTO = new UserLoginDTO();
        userLoginDTO.setToken(JWTUtil.genToken(claim));
        userLoginDTO.setUser(dbUser);
        return userLoginDTO;
    }

    /**
     * 根据验证码进行登录
     * @param codeParam 验证码登录参数
     * @return DTO对象
     */
    private UserLoginDTO loginByCode(UserLoginVerifyCodeParam codeParam) {
//        // 1. 校验参数
//        if (codeParam == null) {
//            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_PARAM_NULL);
//        }
//        // 2. 校验手机号码格式
//        if (!RegexUtil.checkMobile(codeParam.getPhoneNumber())) {
//            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_PHONE_ERROR);
//        }
//        // 3. 校验用户身份信息
//        UserDO dbUser = userMapper.selectByPhoneNumber(new PhoneNumberEncrypt(codeParam.getPhoneNumber()));
//        if (dbUser == null) {
//            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_NOT_EXISTS);
//        }
//        if (StringUtils.hasText(codeParam.getMandatory())
//                && !codeParam.getMandatory()
//                    .equalsIgnoreCase(dbUser.getIdentity())) {
//            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_IDENTITY_ERROR);
//        }
//        // 4. 校验用户验证码
//        String code = verificationCodeService.getVerifyCode(codeParam.getPhoneNumber());
//        if (!StringUtils.hasText(codeParam.getCaptchaCode())
//                || !codeParam.getCaptchaCode().equals(code)) {
//            throw new ServiceException(ServiceErrorCodeConstants.USER_LOGIN_CODE_ERROR);
//        }
//        // 5. 封装DTO返回对象
//        UserLoginDTO userLoginDTO = new UserLoginDTO();
//        Map<String, Object> claim = new HashMap<>();
//        claim.put("id", dbUser.getId());
//        userLoginDTO.setToken(JWTUtil.genToken(claim));
//        userLoginDTO.setIdentity(dbUser.getIdentity());
//        return userLoginDTO;
        return null;
    }

    @Override
    public UserRegisterDTO register(UserRegisterParam param) {
        // 校验用户身份信息
        checkUserInfo(param);
        // 用户密码、邮箱加密存库
        UserDO userDO = new UserDO();
        userDO.setUserName(param.getUserName());
        userDO.setPassword(EncryptUtil.encryptBySha256(param.getPassword()));
        userDO.setUserPhone(new PhoneNumberEncrypt(param.getPhoneNumber()));
        userMapper.insert(userDO);
        // 返回dto对象
        UserRegisterDTO dto = new UserRegisterDTO();
        dto.setUserId(userDO.getId());
        return dto;
    }

    /**
     * 校验用户基本信息
     * @param param 用户注册参数
     */
    private void checkUserInfo(UserRegisterParam param) {
        // 0. 校验用户参数
        if (param == null) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_REG_PARAM_NULL);
        }
        // 1. 校验用户手机号格式
        if (!RegexUtil.checkMobile(param.getPhoneNumber())) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_REG_MOBILE_ERROR);
        }
        // 4. 校验用户密码信息
        if (StringUtils.hasText(param.getPassword())
            && !RegexUtil.checkPassword(param.getPassword())) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_REG_PWD_ERROR);
        }
    }
}
